package com.gzz.orchid.common.core.support;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 注册到SPRING上下文中。
 * 领域注册表
 *
 * @author higmd
 */
public class ContextBeanRegistry implements ApplicationContextAware {
    //Spring应用上下文
    private static ApplicationContext applicationContext;

    /**
     * 发布事件
     *
     * @param event
     * @param <T>
     */
    public static <T> void publish(T event) {
        applicationContext.publishEvent(event);
    }

    /**
     * 获取BEAN, 自动转型为所赋值对象的类型
     */
    public static <T> T getBean(Class<T> clazz) {
        if (Objects.isNull(applicationContext)) {
            throw new IllegalStateException("ApplicationContext is not initialized yet!");
        }
        return applicationContext.getBean(clazz);
    }

    /**
     * 按bean名称获取bean对象
     */
    public static Object getBeanByName(String beanName) {
        if (Objects.isNull(applicationContext)) {
            throw new RuntimeException("applicationContext对象为空。");
        }
        if (!applicationContext.containsBean(beanName)) {
            throw new RuntimeException("找不到" + beanName + " 实例对象。");
        }
        return applicationContext.getBean(beanName);
    }

    /**
     * 获取指定id的bean
     */
    public static Object getObject(String id) {
        return applicationContext.getBean(id);
    }

    /**
     * 获取指定类型所有bean
     */
    public static <T> List<T> beanList(Class<T> clazz) {
        Map<String, T> beans = beanMap(clazz);
        //List<T> t = beans.values().stream().collect(Collectors.toList());
        List<T> t = new ArrayList<>(beans.values());
        return t;
    }

    /**
     * 获取指定类型所有bean
     */
    public static <T> Map<String, T> beanMap(Class<T> clazz) {
        if (Objects.isNull(applicationContext)) {
            throw new RuntimeException("applicationContext对象为空。");
        }
        return applicationContext.getBeansOfType(clazz);
    }

    // 当Spring容器创建该类的实例时，会自动调用此方法，注入应用上下文
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if (Objects.isNull(ContextBeanRegistry.applicationContext)) {
            ContextBeanRegistry.applicationContext = applicationContext;
        }
    }
}
